﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;//增加
using System.Text;
using System.Text.RegularExpressions;//增加
using System.Threading;

namespace 谁与争锋可视化设计
{
    public class PageRequest
    {
        //用户基本信息页面
        string m_baseMessagePage;
        public string BaseMessagePage
        {
            get { return m_baseMessagePage; }
            set { m_baseMessagePage = value; }
        }

        string m_acProblemPage;
        public string AcProblemPage
        {
            get { return m_acProblemPage; }
            set { m_acProblemPage = value; }
        }

        //ac题目总数
        int m_acProblemSum;
        public int AcProblemSum
        {
            get { return m_acProblemSum; }
        }

        //用于通知进度条更新进度
        private System.ComponentModel.BackgroundWorker m_extractProgress;
        public System.ComponentModel.BackgroundWorker ExtractProgress
        {
            get { return m_extractProgress; }
            set { m_extractProgress = value; }
        }

        //当前提取到的题目页面数
        private int m_htmlCount = 0;

        //双线程使用
        private int m_first = 1000000;
        private int m_last = 0;
        private string m_prevPageUrl;
        private bool m_extract = true;
        private bool m_mutex = true;//互斥处理


        public void GetBaseMessagePage(string userName)
        {
            string url = "http://acm.hdu.edu.cn/userstatus.php?user=" + userName;
            m_baseMessagePage = GetHtml(url);

            //获取ac做题总数
            string pattern = @"<td>Accepted</td><td align=center>[0-9]*(?=</td>)";
            MatchCollection matches = Regex.Matches(m_baseMessagePage, pattern);
            Match match = matches[0];
            string message = match.ToString();
            m_acProblemSum = int.Parse(match.ToString().Substring(34));
           
        }

        public void GetAcProblemPage()
        {
            StringBuilder acProblemPages = new StringBuilder();

            //开始提取用户的所有ac题目页面
            string pattern = "'[^']*'(?=>Last accepted submissions)";
            MatchCollection matches = Regex.Matches(m_baseMessagePage, pattern);

            string url = "http://acm.hdu.edu.cn//";////////////
            Match match = matches[0];
            string message = match.ToString();
            string html;

            //去掉引号
            string href = message.Substring(1, message.Length - 2);
            url += href;

            bool once = true;
            do
            {
                html = GetHtml(url);

                if (m_mutex)
                {
                    m_mutex = false;

                    pattern = "\"[^\"]*\"(?=>Next Page)";
                    matches = Regex.Matches(html, pattern);

                    if (once)
                    {
                        pattern = "\"[^\"]*\"(?=>Last Page)";
                        MatchCollection lastMatches = Regex.Matches(html, pattern);
                        Match lastMatch = lastMatches[0];
                        message = lastMatch.ToString();
                        href = message.Substring(1, message.Length - 2);
                        url = "http://acm.hdu.edu.cn" + href;
                        string lastHtml = GetHtml(url);

                        pattern = "\"[^\"]*\"(?=>< Prev Page)";
                        lastMatches = Regex.Matches(lastHtml, pattern);

                        //判断有没有 Prev Page语句,有的话则开启双线程运算
                        if (lastMatches.Count != 0)
                        {
                            lastMatch = lastMatches[0];
                            m_prevPageUrl = lastMatch.ToString().Substring(1, message.Length - 2);

                            //提取出runtimeID
                            pattern = "(?<=last=)[0-9]*";
                            lastMatches = Regex.Matches(lastMatch.ToString(), pattern);
                            lastMatch = lastMatches[0];
                            m_last = int.Parse(lastMatch.ToString());

                            //开启另一个线程从后往前提取               
                            ThreadStart extractStart = new ThreadStart(ExtractHtmlThread);
                            Thread extract = new Thread(extractStart);
                            extract.Start();

                            //last页面加入acProblemPage集合中
                            acProblemPages.Append(lastHtml);
                        }

                        once = false;
                    }


                    if (m_extract)
                    {
                        acProblemPages.Append(html);

                        if (matches.Count != 0)
                        {
                            url = "http://acm.hdu.edu.cn";
                            match = matches[0];
                            message = match.ToString();
                            href = message.Substring(1, message.Length - 2);
                            url += href;
                            m_htmlCount += 15;

                            //提取出runtimeID
                            pattern = "(?<=first=)[0-9]*";
                            matches = Regex.Matches(match.ToString(), pattern);
                            match = matches[0];
                            m_first = int.Parse(match.ToString());

                            //进度条显示
                            m_extractProgress.ReportProgress(m_htmlCount, String.Format("当前提取到的题目数: {0} ", m_htmlCount));

                        }                 
                        else
                        {
                            m_htmlCount = m_acProblemSum;

                            //进度条显示
                            m_extractProgress.ReportProgress(m_htmlCount, String.Format("当前提取到的题目数: {0} ", m_htmlCount));
                            break;
                        }
                    }

                    //双线程关闭后跳转到这里
                    else
                    {
                        m_htmlCount = m_acProblemSum;

                        //进度条显示
                        m_extractProgress.ReportProgress(m_htmlCount, String.Format("当前提取到的题目数: {0} ", m_htmlCount));
                        break;
                    }
                    m_mutex = true;
                }            

            } while (true);

            m_acProblemPage += acProblemPages.ToString();
        }

        private string GetHtml(string url)
        {
            byte[] buf = new WebClient().DownloadData(url);
            return Encoding.UTF8.GetString(buf);
        }

        private void ExtractHtmlThread()
        {
            StringBuilder acProblemPages = new StringBuilder();
            string url = "http://acm.hdu.edu.cn/" +m_prevPageUrl;

            do
            {
                string html = GetHtml(url);

                if (m_mutex)
                {
                    m_mutex = false;
                    string pattern = "\"[^\"]*\"(?=>< Prev Page)";
                    MatchCollection matches = Regex.Matches(html, pattern);


                    if (matches.Count != 0)
                    {
                        url = "http://acm.hdu.edu.cn";
                        Match match = matches[0];
                        string message = match.ToString();
                        string href = message.Substring(1, message.Length - 2);
                        url += href;             

                        //提取出runtimeID
                        pattern = "(?<=last=)[0-9]*";
                        matches = Regex.Matches(url, pattern);
                        match = matches[0];
                        m_last = int.Parse(match.ToString());

                        m_htmlCount += 15;
                        acProblemPages.Append(html);

                        if (m_last >= m_first)
                        {
                            m_extract = false;
                            m_mutex = true;
                            break;
                        }

                        //进度条显示
                        m_extractProgress.ReportProgress(m_htmlCount, String.Format("当前提取到的题目数: {0} ", m_htmlCount));
                    }
                    m_mutex = true;
                }
               
            } while (true);

            m_acProblemPage += acProblemPages.ToString();
        }

    }

}

